//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V1.0.0
/********************************************************
    说明：
    1、独立IO序号0开始，矩阵IO在独立IO后面依次排序。
**********************************************************/
#include "io_ctrl_driver.h"
#include <string.h>
#include <stdio.h>


/* 独立IO */
#ifdef Independent_IO
static volatile unsigned int* WHT_IO_Ctrl_Independent_State[Independent_IO_Count];

static void WHT_IO_Ctrl_Independent_GPIO_Init(void)
{
	WHT_GPIO_BSP.WHT_Set_Clock(Independent0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Independent1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Independent2_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Output(Independent0_GPIO_Port, Independent0_GPIO_Pin, &WHT_IO_Ctrl_Independent_State[0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Independent1_GPIO_Port, Independent1_GPIO_Pin, &WHT_IO_Ctrl_Independent_State[1]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Independent2_GPIO_Port, Independent2_GPIO_Pin, &WHT_IO_Ctrl_Independent_State[2]);

    *WHT_IO_Ctrl_Independent_State[0] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Independent_State[1] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Independent_State[2] = IO_Ctrl_OFF;

	WHT_GPIO_BSP.WHT_Set_Mode(Independent0_GPIO_Port, Independent0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Independent1_GPIO_Port, Independent1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Independent2_GPIO_Port, Independent2_GPIO_Pin, Mode_Out_PP);
}
#endif

/* 矩阵IO */
#ifdef Matrix_IO
static volatile unsigned int* WHT_IO_Ctrl_Matrix_Row_State[Matrix_Row];
static volatile unsigned int* WHT_IO_Ctrl_Matrix_Col_State[Matrix_Col];
static volatile unsigned char WHT_IO_Ctrl_Matrix_State[Matrix_Row][Matrix_Col];

static void WHT_IO_Ctrl_Matrix_GPIO_Init(void)
{
    memset(&WHT_IO_Ctrl_Matrix_State, IO_Ctrl_OFF, Matrix_Row * Matrix_Col);
    //行配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_ROW0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_ROW1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_ROW2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_ROW3_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_ROW4_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_ROW0_GPIO_Port, Matrix_ROW0_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Row_State[0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_ROW1_GPIO_Port, Matrix_ROW1_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Row_State[1]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_ROW2_GPIO_Port, Matrix_ROW2_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Row_State[2]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_ROW3_GPIO_Port, Matrix_ROW3_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Row_State[3]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_ROW4_GPIO_Port, Matrix_ROW4_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Row_State[4]);

    *WHT_IO_Ctrl_Matrix_Row_State[0] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Row_State[1] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Row_State[2] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Row_State[3] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Row_State[4] = IO_Ctrl_OFF;

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_ROW0_GPIO_Port, Matrix_ROW0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_ROW1_GPIO_Port, Matrix_ROW1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_ROW2_GPIO_Port, Matrix_ROW2_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_ROW3_GPIO_Port, Matrix_ROW3_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_ROW4_GPIO_Port, Matrix_ROW4_GPIO_Pin, Mode_Out_PP);
    //列配置
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_COL0_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_COL1_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_COL2_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_COL3_GPIO_Port, ENABLE);
	WHT_GPIO_BSP.WHT_Set_Clock(Matrix_COL4_GPIO_Port, ENABLE);

	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_COL0_GPIO_Port, Matrix_COL0_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Col_State[0]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_COL1_GPIO_Port, Matrix_COL1_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Col_State[1]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_COL2_GPIO_Port, Matrix_COL2_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Col_State[2]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_COL3_GPIO_Port, Matrix_COL3_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Col_State[3]);
	WHT_GPIO_BSP.WHT_Register_Bit_Output(Matrix_COL4_GPIO_Port, Matrix_COL4_GPIO_Pin, &WHT_IO_Ctrl_Matrix_Col_State[4]);

    *WHT_IO_Ctrl_Matrix_Col_State[0] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Col_State[1] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Col_State[2] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Col_State[3] = IO_Ctrl_OFF;
    *WHT_IO_Ctrl_Matrix_Col_State[4] = IO_Ctrl_OFF;

	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_COL0_GPIO_Port, Matrix_COL0_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_COL1_GPIO_Port, Matrix_COL1_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_COL2_GPIO_Port, Matrix_COL2_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_COL3_GPIO_Port, Matrix_COL3_GPIO_Pin, Mode_Out_PP);
	WHT_GPIO_BSP.WHT_Set_Mode(Matrix_COL4_GPIO_Port, Matrix_COL4_GPIO_Pin, Mode_Out_PP);
}
static void WHT_IO_Ctrl_Set_Matrix_Col_Value(unsigned char Row)
{
    static unsigned char Col;
    
    for (Col = 0; Col < Matrix_Col; Col++)
    {
        *WHT_IO_Ctrl_Matrix_Col_State[Col] = WHT_IO_Ctrl_Matrix_State[Row][Col];
    }
}
/* 矩阵IO需要放置定时器中断回调里运行 */
void WHT_IO_Ctrl_Scan_Matrix_Callback(void)
{
    static unsigned char Row = 0;

    switch (Row)
    {
    case 0:
        *WHT_IO_Ctrl_Matrix_Row_State[4] = IO_Ctrl_OFF;
        WHT_IO_Ctrl_Set_Matrix_Col_Value(0);
        *WHT_IO_Ctrl_Matrix_Row_State[0] = IO_Ctrl_ON;
        break;
    case 1:
        *WHT_IO_Ctrl_Matrix_Row_State[0] = IO_Ctrl_OFF;
        WHT_IO_Ctrl_Set_Matrix_Col_Value(1);
        *WHT_IO_Ctrl_Matrix_Row_State[1] = IO_Ctrl_ON;
        break;
    case 2:
        *WHT_IO_Ctrl_Matrix_Row_State[1] = IO_Ctrl_OFF;
        WHT_IO_Ctrl_Set_Matrix_Col_Value(2);
        *WHT_IO_Ctrl_Matrix_Row_State[2] = IO_Ctrl_ON;
        break;
    case 3:
        *WHT_IO_Ctrl_Matrix_Row_State[2] = IO_Ctrl_OFF;
        WHT_IO_Ctrl_Set_Matrix_Col_Value(3);
        *WHT_IO_Ctrl_Matrix_Row_State[3] = IO_Ctrl_ON;
        break;
    case 4:
        *WHT_IO_Ctrl_Matrix_Row_State[3] = IO_Ctrl_OFF;
        WHT_IO_Ctrl_Set_Matrix_Col_Value(4);
        *WHT_IO_Ctrl_Matrix_Row_State[4] = IO_Ctrl_ON;
        Row = 0;
        break;
    default:
        break;
    }
}
#endif


void WHT_IO_Ctrl_Set_Value(WHT_IO_Ctrl_enum number, WHT_IO_Ctrl_State_enum state)
{
#ifdef Independent_IO
    if (number < Independent_IO_Count)
    {
        *WHT_IO_Ctrl_Independent_State[number] = state;
        return;
    }
#endif

#ifdef Matrix_IO
    if (number < IO_Ctrl_Sum_Count)
    {
        WHT_IO_Ctrl_Matrix_State[number/Matrix_Col][number%Matrix_Col] = state;
        return;
    }
#endif
}
void WHT_IO_Ctrl_Init(void)
{
#ifdef Independent_IO
    WHT_IO_Ctrl_Independent_GPIO_Init();
#endif

#ifdef Matrix_IO
    WHT_IO_Ctrl_Matrix_GPIO_Init();
#endif
}
